package cn.sharp.bbs.service.impl;

import cn.sharp.bbs.common.Utils;
import cn.sharp.bbs.common.page.PageParam;
import cn.sharp.bbs.dao.admin.RoleManageDao;
import cn.sharp.bbs.dao.gen.PermissionMapper;
import cn.sharp.bbs.dao.gen.RoleMapper;
import cn.sharp.bbs.entity.BO.PermNode;
import cn.sharp.bbs.entity.DO.Permission;
import cn.sharp.bbs.entity.DO.Rolepermission;
import cn.sharp.bbs.service.RoleManageService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Transactional
@Service
public class RoleManageServiceImpl implements RoleManageService {
    @Resource
    RoleManageDao roleManageDao;
    @Resource
    RoleMapper roleMapper;
    @Resource
    PermissionMapper permissionMapper;

    /**
     * 查询角色列表页
     * @param pageParam 分页参数
     * @return 分页的列表结果
     */
    @Override
    public Map<String, Object> getRoleList(PageParam pageParam) {
        return Utils.getPage(pageParam, roleMapper::selectAll);
    }

    /**
     * 获取角色的分页权限节点列表
     * @param role_id 角色id
     * @param pageParam 分页参数
     * @return 分页结果
     */
    @Override
    public Map<String, Object> getRolePerms(Long role_id, PageParam pageParam) {
        return Utils.getPage(pageParam, ()->getAllPermRole(role_id));
    }

    private List<PermNode> getAllPermRole(Long role_id){
        List<PermNode> permNodes = roleManageDao.getRolePerms();
        permNodes = permNodes.stream().peek(permNode -> {
            permNode.setHasChild(roleManageDao.getSubPerms(permNode.getPid()).size()>0);
            permNode.setChecked(roleManageDao.countByRoleAndPerm(role_id, permNode.getPid())>0);
        }).collect(Collectors.toList());
        return permNodes;
    }

    /**
     * 为角色设置权限
     * @param role_id 角色id
     * @param perms 权限id列表
     */
    @Override
    public void setRolePerms(Long role_id, Long[] perms) {
        List<Long> allPerms = permissionMapper.selectAll().stream()
                .map(Permission::getId).collect(Collectors.toList());
        List<Long> currentPerms = roleManageDao.listPermForRole(role_id);
        List<Long> targetPerms = Arrays.asList(perms);
        List<Rolepermission> include = targetPerms.stream().filter(perm->!currentPerms.contains(perm))
                .map(perm->{
                    Rolepermission roleperm = new Rolepermission();
                    roleperm.setRoleId(role_id);
                    roleperm.setPerId(perm);
                    return roleperm;
                }).collect(Collectors.toList());
        List<Rolepermission> exclude = currentPerms.stream().filter(perm->!targetPerms.contains(perm))
                .map(perm->{
                    Rolepermission roleperm = new Rolepermission();
                    roleperm.setRoleId(role_id);
                    roleperm.setPerId(perm);
                    return roleperm;
                }).collect(Collectors.toList());
        if(include.size()>0)
            roleManageDao.addPermsToRole(include);
        if(exclude.size()>0)
            roleManageDao.delPermsFromRole(exclude);
    }

    /**
     * 检查角色id是否无效
     * @param role_id 角色id
     * @return 布尔值, 是否无效
     */
    @Override
    public boolean isInvalidRole(Long role_id) {
        return roleMapper.selectByPrimaryKey(role_id)==null;
    }

    /**
     * 检查权限id是否无效
     * @param perm_id 权限id
     * @return 布尔值, 是否无效
     */
    @Override
    public boolean isInvalidPerm(Long perm_id) {
        return permissionMapper.selectByPrimaryKey(perm_id)==null;
    }
}
